#ifdef CHANGED

#include "copyright.h"
#include "system.h"
#include "synchconsole.h"
#include "synch.h"

static Semaphore *readAvail;
static Semaphore *writeDone;
static Semaphore *readLock;
static Semaphore *writeLock;

static void ReadAvail(int arg) 
{ 
	readAvail->V(); 
}
static void WriteDone(int arg) 
{ 
	writeDone->V(); 
}

SynchConsole::SynchConsole(char *readFile, char *writeFile)
{	
	readAvail = new Semaphore("read avail", 0);
	writeDone = new Semaphore("write done", 0);
	readLock = new Semaphore("readLock",1);
	writeLock = new Semaphore("writeLock",1);
	console = new Console(readFile, writeFile,ReadAvail, WriteDone,0);
}

SynchConsole::~SynchConsole()
{
	delete console;
	delete writeDone;
	delete readAvail;
} // clean up sychconsole emulation

void SynchConsole::SynchPutChar(const char ch)
{
	writeLock->P();
	console->PutChar(ch);
	writeDone->P();	
	writeLock->V();	  
}

char SynchConsole::SynchGetChar()
{
	readLock->P();
	readAvail->P();
	char ch = console->GetChar();
	readLock->V();
	return ch;
}

void SynchConsole::SynchPutString(const char s[])
{
	writeLock->P();
	while(*s!=EOF && *s!='\0'){
		console->PutChar(*s);
		writeDone->P();
	}
	writeLock->V();
}

void SynchConsole::SynchGetString(char *s, int n)
{
	readLock->P();
	int i = 0;
	char ch;
	if (n!=0){
		readAvail->P();
		ch = console->GetChar();
		s[i] = ch;
		i++;	
	}
	while(i<n && ch!=EOF){
		readAvail->P();
		ch = console->GetChar();
		if((s[i]=ch)=='\n')
			break;
		i++;
	}
	if(n>1){
		if(i<n)
			s[i]='\0';
		else
			s[i-1]='\0';
	}
	readLock->V();
}

void copyStringFromMachine(int from, char *to, unsigned int size){
	writeLock->P ();
	int tmp;
	unsigned int i;
	for(i=0;i<size;i++) {
	  if(machine->ReadMem(from+i,1,&tmp))
		to[i]=tmp;
	  if(tmp == '\0')
	    break;
	}
	if(i<size)
	  to[size-1] = '\0';
	writeLock->V ();
}

void copyStringToMachine(int to, char *from, unsigned int size){
	writeLock->P ();
	int tmp;
	unsigned int i;
	for(i=0;i<=size;i++){
		tmp=from[i];
	    	machine->WriteMem(to+i,1,tmp);
	}
	writeLock->V ();
}

#endif // CHANGED
